
export enum BulletSide {
    None = 0, //没有碰撞
    Top = 1,
    Right = 2,
    Bottom = 3,
    Left = 4,
};
export class PhysicsMath {
    //点是否接近边的任意顶点。
    static FuzzyEqualsV2Arr(v2: cc.Vec2, arr: cc.Vec2[], fuzzyVal: number = 0) {
        for (let i = 0; i < arr.length; i++) {
            if (!v2.fuzzyEquals(arr[i], fuzzyVal)) {
                return false;
            }
        }
        return true;
    }
    // 计算两个矩形中心之间的距离
    static Distance(rect1: cc.Rect, rect2: cc.Rect): cc.Vec2 {
        return cc.v2(
            rect2.center.x - rect1.center.x,
            rect2.center.y - rect1.center.y
        );
    }
    // 判断两个矩形是否重叠
    static IsOverlap(rect1: cc.Rect, rect2: cc.Rect) {
        return (
            rect1.x < rect2.x + rect2.width &&
            rect1.x + rect1.width > rect2.x &&
            rect1.y < rect2.y + rect2.height &&
            rect1.y + rect1.height > rect2.y
        );
    }
    //计算两个矩形的最小平移量。(质量影响)
    static CalculateMinTranslationVector(rectA: cc.Rect, rectB: cc.Rect, mass1: number = 0.5, mass2: number = 0.5): [cc.Vec2, cc.Vec2] {
        // 如果矩形不重叠，则最小平移向量为0
        if (!PhysicsMath.IsOverlap(rectA, rectB)) {
            return [cc.v2(), cc.v2()];
        }

        // 计算两个矩形中心之间的距离
        let dist = PhysicsMath.Distance(rectA, rectB);

        // 计算最小平移向量
        // 使用质量来决定平移分量，质量越小，平移分量越大
        let totalMass = mass1 + mass2;
        let ratioA = mass1 / totalMass;
        let ratioB = mass2 / totalMass;

        let mtvA = cc.v2(
            -dist.x * ratioA,
            -dist.y * ratioA
        );

        let mtvB = cc.v2(
            dist.x * ratioB,
            dist.y * ratioB
        );

        return [mtvA, mtvB];
    }
    static SegmentsIntr(seg1: cc.Vec2[], seg2: cc.Vec2[]) {
        let [a, b] = seg1;
        let [c, d] = seg2;
        /** 1 解线性方程组, 求线段交点. **/
        // 如果分母为0 则平行或共线, 不相交  
        var denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y);
        if (denominator == 0) {
            return null;
        }

        // 线段所在直线的交点坐标 (x , y)      
        var x = ((b.x - a.x) * (d.x - c.x) * (c.y - a.y)
            + (b.y - a.y) * (d.x - c.x) * a.x
            - (d.y - c.y) * (b.x - a.x) * c.x) / denominator;
        var y = -((b.y - a.y) * (d.y - c.y) * (c.x - a.x)
            + (b.x - a.x) * (d.y - c.y) * a.y
            - (d.x - c.x) * (b.y - a.y) * c.y) / denominator;

        /** 2 判断交点是否在两条线段上 **/
        if (
            // 交点在线段1上  
            (x - a.x) * (x - b.x) <= 0 && (y - a.y) * (y - b.y) <= 0
            // 且交点也在线段2上  
            && (x - c.x) * (x - d.x) <= 0 && (y - c.y) * (y - d.y) <= 0
        ) {

            // 返回交点p  
            return cc.v2(x, y);
        }
        //否则不相交  
        return null;
    }


    static CheckCollision(rect1: cc.Rect, rect2: cc.Rect, yFix = 0): number {
        // 计算两个矩形在x轴和y轴上的投影重叠量
        let overlapX = Math.min(rect1.x + rect1.width, rect2.x + rect2.width) - Math.max(rect1.x, rect2.x);
        let overlapY = Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - Math.max(rect1.y, rect2.y);

        // 如果没有重叠，则没有碰撞
        if (overlapX <= 0 || overlapY <= 0) {
            return BulletSide.None;
        }

        // 确定碰撞方向
        if (overlapX < overlapY + yFix) {
            // 如果rect2的右侧在rect1的左侧，那么碰撞方向是左侧
            // if (rect2.xMax <= rect1.xMax) {
            //     return BulletSide.Left;
            // } else {
            //     return BulletSide.Right;
            // }

            if (Math.abs(rect2.xMax - rect1.xMin) >= Math.abs(rect2.xMin - rect1.xMax)) {//更接近右边
                return BulletSide.Right;
            }
            else {//更接近左边
                return BulletSide.Left;
            }
        } else {
            // 如果rect2的底部在rect1的顶部，那么碰撞方向是顶部
            // if (rect2.yMax <= rect1.yMax) {
            //     return BulletSide.Top;
            // } else {
            //     return BulletSide.Bottom;
            // }

            if (Math.abs(rect2.yMax - rect1.yMin) >= Math.abs(rect2.yMin - rect1.yMax)) {//更接近顶部
                return BulletSide.Top;
            }
            else {//更接近底部
                return BulletSide.Bottom;
            }
        }
    }

    // 计算两条线段在一条直线上的相交长度
    static IntersectionXLength(seg1Start: number, seg1End: number, seg2Start: number, seg2End: number) {
        // 确保seg1.start <= seg1.end 和 seg2.start <= seg2.end
        if (seg1Start > seg1End) {
            [seg1Start, seg1End] = [seg1End, seg1Start];
        }
        if (seg2Start > seg2End) {
            [seg2Start, seg2End] = [seg2End, seg2Start];
        }

        // 检查是否有重叠
        const startMax = Math.max(seg1Start, seg2Start);
        const endMin = Math.min(seg1End, seg2End);

        // 如果startMax > endMin，则线段不相交
        if (startMax > endMin) {
            return 0;
        }

        // 计算相交长度
        return endMin - startMax;
    }
};

window["pm"] = PhysicsMath;